home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / dbwrend / source / cal.c next >
C/C++ Source or Header  |  1989-04-16  |  8KB  |  245 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                  Copyright (c) 1987, David B. Wecker                 *
  4.  *                          All Rights Reserved                         *
  5.  *                                                                      *
  6.  * This file is part of DBW_Render                                      *
  7.  *                                                                      *
  8.  * DBW_Render is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts               *
  10.  * responsibility to anyone for the consequences of using it or for     *
  11.  * whether it serves any particular purpose or works at all, unless     *
  12.  * he says so in writing. Refer to the DBW_Render General Public        *
  13.  * License for full details.                                            *
  14.  *                                                                      *
  15.  * Everyone is granted permission to copy, modify and redistribute      *
  16.  * DBW_Render, but only under the conditions described in the           *
  17.  * DBW_Render General Public License. A copy of this license is         *
  18.  * supposed to have been given to you along with DBW_Render so you      *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this     *
  21.  * notice must be preserved on all copies.                              *
  22.  ************************************************************************
  23.  *                                                                      *
  24.  * Authors:                                                             *
  25.  *     DBW - David B. Wecker                                            *
  26.  *                                                                      *
  27.  * Versions:                                                            *
  28.  *     V1.0 870125 DBW  - First released version                        *
  29.  *                                                                      *
  30.  ************************************************************************/
  31.  
  32. #define MODULE_CALC
  33. #include "ray.h"
  34.  
  35. void spherenormal(center,p,n)
  36. vector   center,p,n;
  37. {
  38.      DIRECTION(center,p,n);
  39. }
  40.  
  41. void planenormal(ve,vp,n)
  42. vector ve, vp, n;
  43. {
  44.      cross(vp,ve,n);
  45.      normalize(n);
  46. }
  47.  
  48. void calcripple(point,w,ripple)
  49. vector  point;
  50. int     w;
  51. vector  ripple;
  52. {
  53.      float riprad,temp1,temp2,temp3,damper;
  54.      int iriprad;
  55.  
  56.      direction(point,wave[w].center,ripple); /* unit vector pointing away from wave center */
  57.  
  58.      temp1 = wave[w].center[0] - point[0];
  59.      temp2 = wave[w].center[1] - point[1];
  60.      temp3 = wave[w].center[2] - point[2];
  61.  
  62.      temp1 = temp1 * temp1;  /* square it */
  63.      temp2 = temp2 * temp2;  /* square it */
  64.      temp3 = temp3 * temp3;  /* square it */
  65.  
  66.      riprad = (float)sqrt(temp1 + temp2 + temp3);  /* distance from center to point */
  67.      riprad += wave[w].propagate * wave[w].wavelength;  /* move it */
  68.  
  69.      riprad /= wave[w].wavelength;  /* scale half-wave crest to 0..1 */
  70.      if (wave[w].drag == 1.0) 
  71.           damper = 1.0;
  72.      else 
  73.           damper = (float)pow(wave[w].drag,riprad);  /* exponential damping */
  74.  
  75.      iriprad = (int) riprad;
  76.      if (iriprad & 1)  
  77.      {               /* negate it */
  78.           ripple[0] = -ripple[0];
  79.           ripple[1] = -ripple[1];
  80.           ripple[2] = -ripple[2];
  81.      }
  82.      riprad -= (float) iriprad;  /* just get fraction 0..1 */
  83.      riprad -= 0.5;  /* scale to -0.5 .. +0.5 */
  84.      if (riprad < 0.0) 
  85.           riprad = -riprad;  /* absolute value */
  86.      riprad  = 0.5 - riprad;  /* invert */
  87.      riprad *= damper;
  88.      riprad *= wave[w].amplitude;
  89.      vecscale(riprad,ripple,ripple);  /* scale bend */
  90. }
  91.  
  92. void noise3(point,total)
  93. vector  point,
  94.   total;
  95. {
  96.      vector ripple;
  97.      float s;
  98.      int w;
  99.  
  100.      veczero(total);
  101.      for (w = 0; w < numwaves; w++) 
  102.      {
  103.           calcripple(point,w,ripple);  /* calculate the wave perturbation */
  104.           vecsum(ripple,total,total); /* sum the ripple bends */
  105.      }
  106.      s = NORM(total);
  107.      if (s < 0.001) 
  108.           total[0] = 1.0;
  109.      else 
  110.      {
  111.           s = 1.0 / s;
  112.           vecscale(s,total,total);  /* Make it unit vector */
  113.      }
  114. }
  115.  
  116.  
  117. float noise(point)
  118. vector point;
  119. {
  120.      vector total;
  121.      float s;
  122.  
  123.      noise3(point,total);
  124.      s = total[0] + total[1] + total[2];  /* sum is between -sqrt(3)..+sqrt(3) */
  125.      s += sqrt3;  /* now between 0.0 and 2*sqrt(3) */
  126.      s /= sqrt3times2;  /* scale to range 0..1 */
  127.  
  128.      return( s );
  129. }
  130.  
  131. float turbulence(point)
  132. vector point;
  133. {
  134.      vector temp;
  135.      float t,scale;
  136.  
  137.      if (numwaves > 0) 
  138.      {
  139.           t = 0.0;
  140.           scale = 1.0;
  141.  
  142.           while (scale < 64.0) 
  143.           {
  144.                vecscale(scale,point,temp);
  145.                t += fabs(noise(temp) / scale);
  146.                scale *= 2.0;
  147.           }
  148.      }
  149.      else 
  150.      {
  151.           t = 1.5;
  152.      }
  153.  
  154.      return( t );
  155. }
  156.  
  157. void dodirection(val,eye2,d2,atten,amblits)
  158. vector val;
  159. vector eye2;
  160. vector d2;
  161. float  atten;
  162. int    amblits;
  163. {
  164.      vector transparency,nextval,best_p,n,temp,q,eye,d;
  165.  
  166. #ifdef MCH_AMIGA
  167.      node *best_obj = 1L;
  168. #else
  169.      node *best_obj = (node *)1L;
  170. #endif
  171.  
  172.      float best_t,qnorm,ddotn,n1,n2;
  173.      int hitnext;
  174.  
  175.      /* make local modifyable copies */
  176.      veccopy(eye2,eye);
  177.      veccopy(d2,d);
  178.      veczero(val);
  179.      CV(1.0,1.0,1.0,transparency);
  180.      all_intersects(eye,d,0);
  181.  
  182.      hitnext = 0;
  183.      while ( best_obj && 
  184.        (transparency[0] > 0.01 ||
  185.        transparency[1] > 0.01 || 
  186.        transparency[2] > 0.01 ) ) 
  187.      {
  188.           best_obj = get_next_intersection(hitnext,best_p,&best_t);
  189.           if (best_obj) 
  190.           {
  191.                getval(nextval,best_obj,best_p,d,atten,amblits);
  192.                vecmul(transparency,nextval,nextval);
  193.                vecsum(val,nextval,val);
  194.                vecmul(best_obj->attr.tra,transparency,transparency);
  195.  
  196.                if (transparency[0] > 0.01 ||  /* Can some light get through? */
  197.                  transparency[1] > 0.01 ||
  198.                  transparency[2] > 0.01)
  199.                     if ((best_obj->attr.idx != idxref) ||  /* Is it refractive? */
  200.                       (best_obj->kind     == SPHERE)) 
  201.                     {               /* Is it a volume object? */
  202.  
  203.                          /* apply refraction by changing ray direction and origin */
  204.  
  205.                          findnormal(best_obj,best_p,n);
  206.                          ddotn = DOT(d,n);
  207.  
  208.                          if (ddotn < 0.0) 
  209.                          {
  210.                               n2 = best_obj->attr.idx;
  211.                               n1 = idxref;
  212.                          }
  213.                          else 
  214.                          {
  215.                               n1 = best_obj->attr.idx;
  216.                               n2 = idxref;
  217.                               n[0] = -n[0];  /* Negate the normal */
  218.                               n[1] = -n[1];
  219.                               n[2] = -n[2];
  220.                               ddotn = -ddotn;
  221.                          }
  222.  
  223.                          vecscale(ddotn,n,temp);
  224.                          vecsub(d,temp,temp);
  225.                          vecscale(n1 / n2,temp,q);
  226.  
  227.                          qnorm = NORM(q);  /* magnitude */
  228.                          if (qnorm >= 1.0)
  229.                               best_obj = NULL;  /* past critical angle,no more light */
  230.                          else 
  231.                          {
  232.                               vecscale(sqrt(1.0-(qnorm*qnorm)),n,temp);
  233.                               vecsub(q,temp,d);
  234.                               veccopy(best_p,eye);
  235.                               hitnext = -1;  /* new direction vector,so re-depth-sort intersections */
  236.                               all_intersects(eye,d,0);  /* Compute intersections with new ray */
  237.                          }
  238.                     }
  239.                hitnext++;
  240.           }
  241.      }
  242.      vecmul(backgroundval,transparency,nextval);
  243.      vecsum(val,nextval,val);
  244. }
  245.